<script setup lang="ts">
import { onShow } from '@dcloudio/uni-app'
import { ref, reactive, PropType } from 'vue'
//预览图片方法

const $props = defineProps({
    typeimg: { type: Boolean, default: false },
    imglist: { type: [Array, String], default: () => [] },
    max: {
        //展示图片最大值
        type: Number,
        default: 1,
    },
    choosenum: {
        //选择图片数
        type: Number,
        default: 6,
    },
    modelMin: { type: Boolean, default: false },
    sourceType: { type: Array as PropType<string[]>, default: () => ['album', 'camera'] },
    compress: { type: Boolean, default: true },
    camera: { type: String as PropType<'front' | 'back'>, default: 'back' },
    maxDuration: {
        validator(val) {
            return Number(val) >= 60
        },
        default: 60,
    },
    // 限制上传的视频时常 单位秒
    uploadMaxDuration: { type: Number, default: 70 },
    // 限制上传的视频大小 单位M
    uploadMaxSize: { type: Number, default: 9999 },
    action: { type: String, default: '' },
    name: {
        //发到后台的文件参数名
        type: String,
        default: 'file',
    },
    formData: {
        //HTTP 请求中其他额外的 form data
        type: Object,
        default: () => {},
    },

    headers: {
        //上传的请求头部
        type: Object,
        default: () => {},
    },
    modelValue: {
        //受控图片列表
        type: [Array, String],
        default: () => [],
    },
    remove: {
        //是否展示删除按钮
        type: Boolean,
        default: true,
    },
    appVideoPoster: {
        //app端视频展示封面 只对app有效
        type: String,
        default: '/static/htz-image-upload/play.png',
    },
    maxleng: {
        type: Number,
        default: 6,
    },
    imgtype: {
        type: String,
        default: 'Array',
    },
    choosetype: {
        type: String,
        default: 'all',
    },
    videolist: {
        type: String,
        default: '',
    },
})
const $emit = defineEmits(['choose-success', 'uploadSuccess', 'uploadFail', 'update:modelValue', 'input', 'imgDelete'])
const data = reactive<{ uploadLists: string[]; mediaTypeData: string[]; previewVideoSrc: string }>({
    uploadLists: [], // 网络路径
    mediaTypeData: ['image', 'video', 'all'],
    previewVideoSrc: '',
})
const show = ref(false)
const autoplayVideo = ref(false)
const currentIndex = ref(0)

onShow(() => {
    // 作用, 用于监听父组件传入的图片列表 是数组还是字符串
    if ($props.imgtype === 'Array') {
        data.uploadLists = $props.imglist as string[]
    } else {
        data.uploadLists = ($props.imglist as string).split(',')
    }
    //判断传入的$props.imglist是否是数组
    if (Array.isArray($props.imglist)) {
        data.uploadLists = $props.imglist as string[]
    } else {
        data.uploadLists = $props.imglist.split(',')
    }
    console.log($props.imglist, '22222222222', data.uploadLists)
})
/**
 * 选择图片或视频
 */
const handleChooseFile = () => {
    if (data.uploadLists.length === $props.maxleng) {
        uni.showToast({ title: `最多可上传${$props.maxleng}张图片`, icon: 'none' })
        return
    }
    let itemList = ref<string[]>([])
    if ($props.choosetype === 'all') {
        itemList.value = ['相册', '视频']
    } else if ($props.choosetype === 'img') {
        itemList.value = ['相册']
    } else if ($props.choosetype === 'video') {
        itemList.value = ['视频']
    }
    uni.showActionSheet({
        itemList: itemList.value,
        success: (res) => {
            if ($props.choosetype === 'video') {
                videoAdd()
            } else if ($props.choosetype === 'img') {
                imgAdd()
            } else if (res.tapIndex === 1) {
                videoAdd()
            } else if (res.tapIndex === 0) {
                imgAdd()
            }

            // if (res.tapIndex === 1) {
            //     videoAdd()
            // } else if (res.tapIndex === 0) {
            //     imgAdd()
            // }
        },
        fail: (res) => {
            console.log(res.errMsg)
        },
    })
}
/**
 * 添加视频
 */
function videoAdd() {
    // if ($props.typeimg) {
    //     uni.showToast({ title: `只能上传图片`, icon: 'none' })
    //     return
    // }
    uni.chooseVideo({
        compressed: $props.compress,
        sourceType: $props.sourceType,
        camera: $props.camera,
        maxDuration: $props.maxDuration,
        success: (res: any) => {
            let type = isvideo(res.tempFile.type)
            if (!type) {
                uni.showToast({ title: `请上传mp4格式的视频`, icon: 'none' })
                return
            }
            // 这里是添加了视频
            if (res.duration > $props.uploadMaxDuration) {
                uni.showToast({
                    title: `上传视频需低于${$props.uploadMaxDuration}秒`,
                    icon: 'none',
                    duration: 2000,
                })
                return
            }
            if (res.size > $props.uploadMaxSize * 1024) {
                uni.showToast({
                    title: `上传视频需小于${$props.uploadMaxSize}M`,
                    icon: 'none',
                    duration: 2000,
                })
                return
            }
            chooseSuccessMethod([res.tempFilePath], 1)
        },
    })
}
/**
 * 添加图片
 */
function imgAdd() {
    let nowNum = Math.abs(data.uploadLists.length - $props.max)
    let thisNum = $props.choosenum > nowNum ? nowNum : $props.choosenum //可选数量
    uni.chooseImage({
        count: thisNum,
        sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图，默认二者都有
        sourceType: $props.sourceType,
        success: (res: any) => {
            console.log(res.tempFiles)
            res.tempFiles.forEach((item: any) => {
                let type = isimage(item.type) //判断图片格式是否支持
                console.log(type)
                if (!type) {
                    uni.showToast({ title: '请上传jpg/jpeg/png格式图片', icon: 'none' })
                    return
                }
                chooseSuccessMethod(res.tempFilePaths as string[], 0)
            })
        },
    })
}
/**
 * 选择成功的方法
 * @param {*} filePaths 路径
 * @param {*} type 0 为图片 1为视频
 */
function chooseSuccessMethod(filePaths: string[], type: 0 | 1) {
    if ($props.action === '') {
        //未配置上传路径
        $emit('choose-success', filePaths, type)
    } else if (type === 1) {
        // 上传视频
        imgUpload(filePaths, type)
    } else {
        // 上传图片
        imgUpload(filePaths, type)
    }
}
/**
 * 选择成功的方法
 * @param {*} tempFilePaths 路径
 * @param {*} type 0 为图片 1为视频
 */
function imgUpload(tempFilePaths: string[], type: 0 | 1) {
    if ($props.action === '') {
        uni.showToast({
            title: '未配置上传地址',
            icon: 'none',
            duration: 2000,
        })
        return false
    }
    let uploadImgs: any[] = []
    tempFilePaths.forEach((item, index) => {
        uploadImgs.push(
            new Promise((resolve, reject) => {
                // uploadFile 上传本地文件
                const uploadTask = uni.uploadFile({
                    url: $props.action,
                    filePath: item, //  本地文件路径
                    name: $props.name,
                    fileType: 'image',
                    formData: $props.formData,
                    header: $props.headers,
                    success: (uploadFileRes: any) => {
                        uploadFileRes.fileType = type
                        if (uploadFileRes.statusCode !== 200) {
                            reject('服务器内部错误')
                            $emit('uploadFail', '服务器内部错误')
                            return
                        }
                        if (uploadFileRes.data) {
                            const url: string = JSON.parse(uploadFileRes.data).data
                            if ($props.choosetype === 'video') {
                                $emit('update:modelValue', url as string)
                                return
                            }
                            data.uploadLists.push(url)
                            console.log($props.imglist)
                            $emit('input', data.uploadLists)
                            $props.imgtype === 'Array'
                                ? $emit('update:modelValue', data.uploadLists as string[])
                                : $emit('update:modelValue', url as string)
                            resolve(uploadFileRes)
                            $emit('uploadSuccess', data.uploadLists)
                        }
                    },
                    fail: (err) => {
                        reject(err)
                        $emit('uploadFail', err)
                    },
                    complete: (res) => {
                        // console.log('res', res)
                    },
                })
                uploadTask.onProgressUpdate((res) => {
                    // 先执行
                    uni.showLoading({
                        title: '上传中' + res.progress + '%',
                    })
                    if (res.progress === 100) {
                        uni.hideLoading()
                    }
                })
            }),
        )
    })
    Promise.all(uploadImgs) //执行所有需请求的接口
        .then((results) => {
            uni.hideLoading()
        })
        .catch((res) => {
            uni.hideLoading()
            $emit('uploadFail', res)
        })
}
/**
 * 预览图片方法
 * @param {*} item
 */
function imgPreview(index: number, imageList: string[]) {
    // 预览图片
    const imgData: string[] = []
    imageList.forEach((item) => {
        imgData.push(item)
    })
    uni.previewImage({
        urls: imgData,
        current: index,
        loop: true,
    })
}
function getFileUrl(item: string) {
    return item
}
function previewVideo(src: string) {
    data.previewVideoSrc = src
    autoplayVideo.value = true
}

function previewVideoClose() {
    autoplayVideo.value = false
    data.previewVideoSrc = ''
}
function imgDel(index: number) {
    show.value = true
    currentIndex.value = index
    // uni.showModal({
    //     title: '提示',
    //     content: '您确定要删除么?',
    //     success: (res) => {
    //         if (res.confirm) {
    //             let delUrl = data.uploadLists[index]
    //             data.uploadLists.splice(index, 1)
    //             $emit('input', data.uploadLists)
    //             $emit('update:modelValue', data.uploadLists)
    //             $emit('imgDelete', {
    //                 del: delUrl,
    //                 tempFilePaths: data.uploadLists,
    //             })
    //         } else if (res.cancel) {
    //             console.log('res', res)
    //         }
    //     },
    // })
}
const handleDelImage = () => {
    if ($props.choosetype === 'video') {
        let a = ''
        $emit('update:modelValue', a)
        show.value = false
        return
    } else {
        data.uploadLists.splice(currentIndex.value, 1)
        $emit('input', data.uploadLists)
        $emit('update:modelValue', data.uploadLists)
        $emit('imgDelete', {
            del: $props.imglist[currentIndex.value],
            tempFilePaths: $props.imglist,
        })
        show.value = false
    }
}

//isimage 传入参数string 判断图片的格式是否是jpg、png 不是的话返回false
function isimage(str: string) {
    // 是否是jpg、png
    let reg = /(.jpg|.jpeg|.png)$/
    return reg.test(str)
}
//isvideo 传入参数string 判断视频的格式是否是mp4 不是的话返回false
function isvideo(str: string) {
    let reg = /(.mp4)$/
    return reg.test(str)
}
</script>

<template>
    <view class="upload-list">
        <!-- 展示图片 -->
        <view v-for="(item, index) in $props.imglist" :key="index" class="upload-list__item">
            <u-image :width="148" :height="148" :src="item" border-radius="10" @click="imgPreview(index, data.uploadLists)" />
            <!-- //删除按钮 -->

            <view v-if="$props.choosetype === 'img'" class="upload-list__del" @click="imgDel(index)">
                <u-icon name="close-circle" size="40rpx" color="#ffffff" />
            </view>
        </view>
        <view style="position: relative">
            <video v-if="$props.videolist" :src="$props.videolist" object-fit="contain" class="upload-list__item--video" :controls="false" />
            <view v-if="$props.videolist" class="upload-list__videodel" @click="imgDel(0)">
                <u-icon name="close-circle" size="40rpx" color="#ffffff" />
            </view>
        </view>
        <!-- 选择图片或视频 s -->
        <view
            v-if="$props.imglist.length !== $props.maxleng && $props.videolist === ''"
            key="choose"
            class="choose"
            :class="{ 'choose--thereAre': data.uploadLists.length }"
            @click="handleChooseFile"
        >
            <u-icon name="plus" size="50" color="#333" />
        </view>
        <!-- 选择图片或视频 e -->
        <!-- <u-mask :show="autoplayVideo" :custom-style="{ backgroundColor: '#000', display: 'flex', alignItems: 'center' }" @click="previewVideoClose">
            <video :src="data.previewVideoSrc" object-fit="contain" class="preview-video" @click.stop="() => {}" />
        </u-mask> -->
    </view>
    <u-modal v-model="show" :show-title="false" :show-confirm-button="false">
        <view class="modal-close" @click="show = false">
            <u-icon name="close-circle" size="50rpx" />
        </view>
        <view class="modal-close__title">确认删除？</view>
        <view class="modal-close__btns">
            <u-button plain shape="circle" :custom-style="{ width: '200rpx', height: '70rpx', color: '#4755E9' }" @click="show = false"
                >取消</u-button
            >
            <u-button
                shape="circle"
                :custom-style="{ width: '200rpx', height: '70rpx', backgroundColor: '#4755E9', color: 'white' }"
                @click="handleDelImage"
                >删除</u-button
            >
        </view>
    </u-modal>
</template>

<style scoped lang="scss">
.a {
    color: red;
}
@include b(upload-list) {
    display: flex;
    flex-wrap: wrap;
    color: white;
    margin-top: 14rpx;
    @include e(item) {
        position: relative;
        width: 148rpx;
        height: 148rpx;
        margin-right: 25rpx;
        @include m(video) {
            width: 320rpx;
            height: 160rpx;
            border-radius: 10rpx;
        }
    }
    @include e(videodel) {
        position: absolute;
        right: -2rpx;
        top: 10rpx;
        z-index: 99999;
    }
    @include e(del) {
        position: absolute;
        right: 10rpx;
        top: 10rpx;
    }
    @include e(autoplay-btn) {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        border-radius: 50%;
        border: 2px solid #fff;
        padding: 5rpx;
        @include flex;
    }
}
@include b(preview-video) {
    width: 100vw;
}
@include b(choose) {
    padding: 54rpx 0;
    width: 148rpx;
    height: 148rpx;
    display: flex;
    justify-content: center;
    flex-direction: column;
    align-items: center;
    background: rgb(244, 245, 246);
    border-radius: 10rpx;
    border: 2rpx dashed rgba(187, 187, 187, 1);
    @include m(thereAre) {
        padding: 54rpx 0;
        width: 148rpx;
        display: flex;
        justify-content: center;
        flex-direction: column;
        align-items: center;
        background: rgb(244, 245, 246);
        border-radius: 20rpx;
    }
    @include m(text) {
        font-size: 18rpx;
        color: #9a9a9a;
        text-align: center;
    }
}
@include b(modal-close) {
    @include flex;
    justify-content: flex-end;
    padding: 10rpx;
    padding-bottom: 0;
    @include e(title) {
        font-size: 35rpx;
        font-weight: 700;
        text-align: center;
    }
    @include e(btns) {
        margin: 50rpx 0 30rpx 0;
        @include flex;
    }
}
</style>
